package com.example.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.enums.Constants;
import com.example.common.utils.R;
import com.example.system.entity.Dict;
import com.example.system.entity.Menu;
import com.example.system.mapper.DictMapper;
import com.example.system.mapper.MenuMapper;
import com.example.system.mapper.RoleMenuMapper;
import com.example.system.service.IMenuService;
import com.example.system.service.IUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 王鹤蒲
 * @since 2023-08-13
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {

    private Logger logger= LoggerFactory.getLogger(MenuServiceImpl.class);

    @Autowired
    private IUserService iUserService;

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private DictMapper dictMapper;

    @Override
    public List<Menu> findAll(String name) {
        LambdaQueryWrapper<Menu> lambdaQueryWrapper = new LambdaQueryWrapper<Menu>();
        lambdaQueryWrapper.eq(Menu::getDelFlag, '0');
        lambdaQueryWrapper.like(StrUtil.isNotBlank(name), Menu::getMenuName,name);
        List<Menu> menuList = menuMapper.selectList(lambdaQueryWrapper);
        List<Menu> parentMenuList = menuList.stream().filter(menu -> menu.getParentId() == null).sorted(Comparator.comparing(Menu::getSortNum)).collect(Collectors.toList());
        for (Menu parentMenu : parentMenuList) {
            List<Menu> subParentMenuList=menuList.stream().filter(menu -> parentMenu.getMenuId().equals(menu.getParentId())).sorted(Comparator.comparing(Menu::getSortNum)).collect(Collectors.toList());
            for(Menu subParentMenu:subParentMenuList){
               subParentMenu.setSubmenuList(menuList.stream().filter(menu->subParentMenu.getMenuId().equals(menu.getParentId())).sorted(Comparator.comparing(Menu::getSortNum)).collect(Collectors.toList()));
            }
            parentMenu.setSubmenuList(subParentMenuList);
        }
        return parentMenuList;
    }

    @Override
    public R findPage(int currentPage, int pageSize, String name) {
        Page<Menu> page = new Page<>(currentPage, pageSize);
        LambdaQueryWrapper<Menu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Menu::getDelFlag, '0');
        lambdaQueryWrapper.like(StrUtil.isNotBlank(name), Menu::getMenuName, name);
        menuMapper.selectPage(page, lambdaQueryWrapper);
        return R.success(page);
    }

    @Override
    public R update(Menu menu) {
        LambdaUpdateWrapper<Menu> lambdaUpdateWrapper = new LambdaUpdateWrapper<Menu>();
        lambdaUpdateWrapper.eq(Menu::getMenuId, menu.getMenuId());
        lambdaUpdateWrapper.eq(Menu::getDelFlag, '0');
        lambdaUpdateWrapper.set(StrUtil.isNotBlank(menu.getMenuName()), Menu::getMenuName, menu.getMenuName());
        lambdaUpdateWrapper.set(StrUtil.isNotBlank(menu.getPath()), Menu::getPath, menu.getPath());
        lambdaUpdateWrapper.set(StrUtil.isNotBlank(menu.getPagePath()),Menu::getPagePath,menu.getPagePath());
        lambdaUpdateWrapper.set(StrUtil.isNotBlank(menu.getIcon()), Menu::getIcon, menu.getIcon());
        lambdaUpdateWrapper.set(Objects.nonNull(menu.getSortNum()),Menu::getSortNum,menu.getSortNum());
        lambdaUpdateWrapper.set(StrUtil.isNotBlank(menu.getDescription()), Menu::getDescription, menu.getDescription());
        lambdaUpdateWrapper.set(Menu::getUpdateBy, iUserService.getCurrentLoginUser().getUserName());
        LocalDateTime updateTime = LocalDateTime.now();
        lambdaUpdateWrapper.set(Menu::getUpdateTime, updateTime);
        menuMapper.update(new Menu(), lambdaUpdateWrapper);
        return R.success();
    }

    @Override
    public R insert(Menu menu) {
        LocalDateTime createTime = LocalDateTime.now();
        menu.setCreateBy(iUserService.getCurrentLoginUser().getUserName()).setCreateTime(createTime);
        menuMapper.insert(menu);
        return R.success();
    }

    @Override
    public R deleteById(Integer id) {
        LambdaUpdateWrapper<Menu> lambdaUpdateWrapper=new LambdaUpdateWrapper<Menu>();
        lambdaUpdateWrapper.eq(Menu::getMenuId,id);
        LocalDateTime deleteTime=LocalDateTime.now();
        menuMapper.update(new Menu().setDelFlag("1").setUpdateBy(iUserService.getCurrentLoginUser().getUserName()).setUpdateTime(deleteTime),lambdaUpdateWrapper);
        roleMenuMapper.deleteByMenuId(id);
        return R.success();
    }

    @Override
    public R deleteByIds(Integer[] ids) {
        LambdaUpdateWrapper<Menu> lambdaUpdateWrapper=new LambdaUpdateWrapper<Menu>();
        LocalDateTime deleteTime=LocalDateTime.now();
        for(Integer id:ids){
            lambdaUpdateWrapper.eq(Menu::getMenuId,id);
            menuMapper.update(new Menu().setDelFlag("1").setUpdateBy(iUserService.getCurrentLoginUser().getUserName()).setUpdateTime(deleteTime),lambdaUpdateWrapper);
            roleMenuMapper.deleteByMenuId(id);
            lambdaUpdateWrapper.clear();
        }
        return R.success();
    }

    @Override
    public R getIconList() {
        LambdaQueryWrapper<Dict> lambdaQueryWrapper=new LambdaQueryWrapper<Dict>();
        lambdaQueryWrapper.eq(Dict::getType, Constants.DICT_TYPE_ICON);
        lambdaQueryWrapper.eq(Dict::getStatus,1);
        return R.success(dictMapper.selectList(lambdaQueryWrapper));
    }

    @Override
    public R selectAllMenuIds(){
        return R.success(menuMapper.selectAllMenuIds());
    }

}
